package com.ibeeking.found.cop.b.rest.service.impl;

import com.aliyun.oss.OSS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.common.config.feign.MsgFeignClient;
import com.ibeeking.found.common.config.prop.FileOssProp;
import com.ibeeking.found.common.constants.DefaultPathConstant;

import com.ibeeking.found.common.entity.msg.EMailSimpleMsgSendParam;
import com.ibeeking.found.common.entity.msg.MsgSimpleParam;
import com.ibeeking.found.common.entity.msg.MsgTemplateParam;
import com.ibeeking.found.common.enums.msg.MsgReceiverTypeEnum;
import com.ibeeking.found.common.enums.msg.MsgTemplateCodeEnum;
import com.ibeeking.found.common.enums.sms.MsgChannelEnum;
import com.ibeeking.found.common.utils.UrlUtils;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.cop.api.feign.FileFeignClient;
import com.ibeeking.found.cop.b.rest.config.prop.FileConfigProp;
import com.ibeeking.found.cop.b.rest.service.IDataTalkService;
import com.ibeeking.found.cop.b.rest.service.IWxOpenService;
import com.ibeeking.found.cop.service.common.bo.DataTalkMsgBO;
import com.ibeeking.found.cop.service.common.constants.FriendsConstant;
import com.ibeeking.found.cop.service.common.constants.RedisKeyConstant;
import com.ibeeking.found.cop.service.common.constants.WxCpDataTalkMediaSuffix;
import com.ibeeking.found.cop.service.common.constants.WxCpDataTalkMsgType;
import com.ibeeking.found.cop.service.common.dos.*;
import com.ibeeking.found.cop.service.common.enums.DataTalkMsgTipEnum;
import com.ibeeking.found.cop.service.common.enums.WxCpDataTalkFriendsAgreeEnum;
import com.ibeeking.found.cop.service.common.enums.WxCpDataTalkFriendsPermitEnum;
import com.ibeeking.found.cop.service.common.param.DataTalkParam;
import com.ibeeking.found.cop.service.common.query.DataTalkQuery;
import com.ibeeking.found.cop.service.common.vo.DataTalkFriendsViewVO;
import com.ibeeking.found.cop.service.common.vo.DataTalkVO;
import com.ibeeking.found.cop.service.common.vo.DataTalkViewItemVO;
import com.ibeeking.found.cop.service.common.vo.DataTalkViewVO;
import com.ibeeking.found.cop.service.mapper.*;
import com.ibeeking.found.id.GenerateId;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.file.oss.config.OssProp;
import com.ibeeking.nematos.file.oss.config.OssService;
import com.ibeeking.nematos.file.oss.dto.OssPolicyDto;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.redis.utils.RedisUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.date.DateUtil;
import com.ibeeking.nematos.utils.file.FileUtils;
import com.ibeeking.nematos.utils.file.OSSUtils;
import com.ibeeking.nematos.utils.id.IdGenerator;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.ibeeking.nematos.utils.result.ResponseResult;
import com.tencent.wework.Finance;
import me.chanjar.weixin.cp.api.WxCpMsgAuditService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.msgaudit.*;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName DataTalkServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-27 18:50
 **/
@Service
public class DataTalkServiceImpl extends ServiceImpl<DataTalkMapper, DataTalkDO> implements IDataTalkService {

    private static String DATE_FORMATTER = "yyyy-MM-dd HH:mm:ss";

    @Resource
    private OSS ossClient;

    @Resource
    private OssProp ossProp;

    @Resource
    private FileOssProp fileOssProp;

    @Resource
    private RedisUtils redisUtils;

    @Autowired
    private FileConfigProp fileConfigProp;

    @Resource
    private CopEmployeeMapper copEmployeeMapper;

    @Resource
    private FriendsMapper friendsMapper;

    @Resource
    private GroupMapper groupMapper;

    @Resource
    private DataTalkMapper dataTalkMapper;

    @Resource
    private DataTalkFriendsMapper dataTalkFriendsMapper;

    @Resource
    private DataTalkFriendsPermitMapper dataTalkFriendsPermitMapper;

    @Resource
    private DataTalkFriendsAgreeMapper dataTalkFriendsAgreeMapper;

    @Resource
    private IWxOpenService wxOpenServiceImpl;

    @Resource
    private FileFeignClient fileFeignClient;

    @Resource
    private MsgFeignClient msgFeignClient;

    @Override
    public Boolean sendMsg(String type){
        if(type.equalsIgnoreCase("1")) {
            MsgSimpleParam simpleParam = new MsgSimpleParam();
            simpleParam.setTenantId(UserUtils.getTenantId());
            simpleParam.setChannel(MsgChannelEnum.EMAIL_MESSAGE.name());
            EMailSimpleMsgSendParam eMailMsgSendParam = new EMailSimpleMsgSendParam();
            eMailMsgSendParam.setContent("this is test!");
            eMailMsgSendParam.setSubject("test Mail");
            List<String> tousers = new ArrayList<>();
            tousers.add("devenwang@21cn.com");
            tousers.add("shwangym@qq.com");
            eMailMsgSendParam.setToUser(tousers);
            simpleParam.setContent(JsonUtils.toJsonStr(eMailMsgSendParam));
            msgFeignClient.sendSimpleMessage(simpleParam);
        }else if(type.equalsIgnoreCase("2")){
            sendPlat();
        }else if(type.equalsIgnoreCase("3")){
            sendBuyer();
        }else if(type.equalsIgnoreCase("4")){
            sendSeller();
        }
        return true;
    }
    private void sendPlat(){
        MsgTemplateParam templateParam = new MsgTemplateParam();
        templateParam.setTenantId(UserUtils.getTenantId());
        templateParam.setTemplateCode(MsgTemplateCodeEnum.PLATFORM_NOTICE_001.getCode());
        Map<String, String> params = new HashMap<>();
        params.put("code","412345");
        params.put("name","张三");
        params.put("company","蜂王公司");
        params.put("link","www.ibeeking.com");
        templateParam.setParamMap(params);
        List<String> tousers = new ArrayList<>();
        tousers.add("36");
        templateParam.setReceivers(tousers);
        templateParam.setReceiverType(MsgReceiverTypeEnum.PLATFORM.getCode());
        msgFeignClient.sendTemplateMessage(templateParam);
    }
    private void sendBuyer(){
        MsgTemplateParam templateParam = new MsgTemplateParam();
        templateParam.setTenantId(UserUtils.getTenantId());
        templateParam.setTemplateCode(MsgTemplateCodeEnum.BUYER_ORDER_001.getCode());
        Map<String, String> params = new HashMap<>();
        params.put("code","312345");
        params.put("name","张三");
        params.put("company","蜂王公司");
        params.put("link","www.ibeeking.com");
        templateParam.setParamMap(params);
        List<String> tousers = new ArrayList<>();
        tousers.add("6809151331434761949");
        templateParam.setReceivers(tousers);
        templateParam.setReceiverType(MsgReceiverTypeEnum.BUYER.getCode());
        msgFeignClient.sendTemplateMessage(templateParam);
    }
    private void sendSeller(){
        MsgTemplateParam templateParam = new MsgTemplateParam();
        templateParam.setTenantId(UserUtils.getTenantId());
        templateParam.setTemplateCode(MsgTemplateCodeEnum.SELLER_ORDER_001.getCode());
        Map<String, String> params = new HashMap<>();
        params.put("code","223456");
        params.put("name","张三");
        params.put("company","蜂王公司");
        params.put("link","www.ibeeking.com");
        templateParam.setParamMap(params);
        List<String> tousers = new ArrayList<>();
        tousers.add("6773937507756409573");
        templateParam.setReceivers(tousers);
        templateParam.setReceiverType(MsgReceiverTypeEnum.BUYER.getCode());
        msgFeignClient.sendTemplateMessage(templateParam);
    }
    @Override
    public List<DataTalkVO> list(DataTalkQuery query) {
        List<DataTalkDO> entityDOS = dataTalkMapper.selectList(new LambdaQueryWrapper<DataTalkDO>()
                .eq(query.getId() != null, DataTalkDO::getId, query.getId())
                .eq(StringUtils.isNotBlank(query.getMsgId()), DataTalkDO::getMsgId, query.getMsgId())
                .eq(StringUtils.isNotBlank(query.getAction()), DataTalkDO::getAction, query.getAction())
                .eq(StringUtils.isNotBlank(query.getMsgType()), DataTalkDO::getMsgType, query.getMsgType())
                .eq(StringUtils.isNotBlank(query.getRoomId()), DataTalkDO::getRoomId, query.getRoomId())
                .like(StringUtils.isNotBlank(query.getContent()), DataTalkDO::getContent, query.getContent())
                .ge(StringUtils.isNotBlank(query.getMsgTimeBegin()), DataTalkDO::getMsgTime, query.getMsgTimeBegin())
                .le(StringUtils.isNotBlank(query.getMsgTimeTo()), DataTalkDO::getMsgTime, query.getMsgTimeTo())
                .orderByDesc(DataTalkDO::getCreateTime)
        );
        List<DataTalkVO> entityVOS = JsonUtils.jsonToList(entityDOS, DataTalkVO.class);
        return entityVOS;
    }

    @Override
    public DataTalkViewVO queryBySenderAndReceiverCode(String senderCode, String receiverCode, Integer type){
        if(StringUtils.isEmpty(senderCode) || StringUtils.isEmpty(receiverCode)) throw new BusinessException("代码不能为空！");
        LambdaQueryWrapper<DataTalkFriendsDO> query = new LambdaQueryWrapper<>();
        query.eq(DataTalkFriendsDO::getType,type);
        query.and(wrapper -> wrapper
                .or().or(wq -> wq.func(i -> i.eq(DataTalkFriendsDO::getSender, senderCode)).func(j -> j.eq(DataTalkFriendsDO::getReceiver, receiverCode)))
                .or().or(wf -> wf.func(i -> i.eq(DataTalkFriendsDO::getSender, receiverCode)).func(j -> j.eq(DataTalkFriendsDO::getReceiver, senderCode)))
        );
        LogUtils.info(">>>>>>>query:{}", query.getTargetSql());
        List<DataTalkFriendsDO> dataTalkFriendsDOS = dataTalkFriendsMapper.selectList(query);
        if(Collections3.isNotEmpty(dataTalkFriendsDOS)) {
            DataTalkFriendsDO dataTalkFriendsDO = dataTalkFriendsDOS.get(0);
            DataTalkViewVO dataTalkView = BeanUtil.convertBean(dataTalkFriendsDO, DataTalkViewVO.class);
            if (dataTalkView != null) {
                if (StringUtils.isEmpty(dataTalkFriendsDO.getSenderName()) && StringUtils.isEmpty(dataTalkFriendsDO.getSenderNickName())) {
                    dataTalkView.setSenderName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                    dataTalkView.setSenderNickName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                }
                if (StringUtils.isEmpty(dataTalkFriendsDO.getReceiverName()) && StringUtils.isEmpty(dataTalkFriendsDO.getReceiverNickName())) {
                    dataTalkView.setReceiverName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                    dataTalkView.setReceiverNickName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                }
                if (StringUtils.isNotEmpty(dataTalkFriendsDO.getSenderAvatar())) {
                    dataTalkView.setSenderAvatar(UrlUtils.addUrlDomainName(fileOssProp.getHost(), dataTalkFriendsDO.getSenderAvatar()));
                } else {
                    dataTalkView.setSenderAvatar(UrlUtils.addUrlDomainName(fileOssProp.getHost(), DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE));
                }
                if (StringUtils.isNotEmpty(dataTalkFriendsDO.getReceiverAvatar())) {
                    dataTalkView.setReceiverAvatar(UrlUtils.addUrlDomainName(fileOssProp.getHost(), dataTalkFriendsDO.getReceiverAvatar()));
                } else {
                    dataTalkView.setReceiverAvatar(UrlUtils.addUrlDomainName(fileOssProp.getHost(), DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE));
                }
            }
            List<Long> allTalkIds = dataTalkFriendsDOS.stream().map(DataTalkFriendsDO::getTalkId).collect(Collectors.toList());
            List<Long> talkIds = Collections3.isNotEmpty(allTalkIds) ? allTalkIds.stream().distinct().collect(Collectors.toList()) : null;
            if (Collections3.isNotEmpty(talkIds)) {
                List<DataTalkViewItemVO> dataTalkLists = new ArrayList<>();
                List<DataTalkViewItemVO.File> fileLists = new ArrayList<>();
                List<DataTalkViewItemVO.File> imageLists = new ArrayList<>();
                List<DataTalkViewItemVO.File> voiceLists = new ArrayList<>();
                List<DataTalkViewItemVO.File> videoLists = new ArrayList<>();
                List<DataTalkDO> entityDOS = dataTalkMapper.selectList(new LambdaQueryWrapper<DataTalkDO>().in(DataTalkDO::getId, talkIds).orderByDesc(DataTalkDO::getMsgTime));
                if (Collections3.isNotEmpty(entityDOS)) {
                    for (DataTalkDO dataTalkDO : entityDOS) {
                        DataTalkViewItemVO dataTalkItemVO = BeanUtil.convertBean(dataTalkDO, DataTalkViewItemVO.class);
                        LocalDateTime createTime = dataTalkDO.getCreateTime();
                        if (createTime != null) {
                            dataTalkItemVO.setCreateTime(DateUtil.localDateTimeToStr(createTime));
                        }
                        LocalDateTime msgTime = dataTalkDO.getMsgTime();
                        if (msgTime != null) {
                            dataTalkItemVO.setMsgTime(DateUtil.localDateTimeToStr(msgTime));
                        }
                        if (senderCode.equalsIgnoreCase(dataTalkDO.getSender())) {
                            dataTalkItemVO.setCode(dataTalkView.getSender());
                            dataTalkItemVO.setName(dataTalkView.getSenderName());
                            dataTalkItemVO.setNickName(dataTalkView.getSenderNickName());
                            dataTalkItemVO.setAvatar(dataTalkView.getSenderAvatar());
                            dataTalkItemVO.setSide("left");
                        } else {
                            dataTalkItemVO.setCode(dataTalkView.getReceiver());
                            dataTalkItemVO.setName(dataTalkView.getReceiverName());
                            dataTalkItemVO.setNickName(dataTalkView.getReceiverNickName());
                            dataTalkItemVO.setAvatar(dataTalkView.getReceiverAvatar());
                            dataTalkItemVO.setSide("right");
                        }
                        String content = dataTalkDO.getContent();
                        if (StringUtils.isNotEmpty(content)) {
                            DataTalkMsgBO dataTalkMsgBO = JsonUtils.fromJson(content, DataTalkMsgBO.class);
                            if (dataTalkMsgBO != null) {
                                if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_TEXT)) {
                                    dataTalkItemVO.setMsgText(dataTalkMsgBO.getText().getContent());
                                } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_IMAGE)) {
                                    if (dataTalkMsgBO.getImage() != null) {
                                        DataTalkViewItemVO.File imageFile = BeanUtil.convertBean(dataTalkMsgBO.getImage(), DataTalkViewItemVO.File.class);
                                        imageFile.setFileType(WxCpDataTalkMsgType.MSG_TYPE_IMAGE);
                                        if (StringUtils.isNotEmpty(imageFile.getFilePath())) {
                                            imageFile.setFilePath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), imageFile.getFilePath()));
                                        }
                                        dataTalkItemVO.setFile(imageFile);
                                        imageLists.add(imageFile);
                                    }
                                } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_VOICE)) {
                                    if (dataTalkMsgBO.getVoice() != null) {
                                        DataTalkViewItemVO.File voiceFile = BeanUtil.convertBean(dataTalkMsgBO.getVoice(), DataTalkViewItemVO.File.class);
                                        voiceFile.setFileType(WxCpDataTalkMsgType.MSG_TYPE_VOICE);
                                        if (StringUtils.isNotEmpty(voiceFile.getFilePath())) {
                                            voiceFile.setFilePath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), voiceFile.getFilePath()));
                                        }
                                        dataTalkItemVO.setFile(voiceFile);
                                        voiceLists.add(voiceFile);
                                    }
                                } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_VIDEO)) {
                                    if (dataTalkMsgBO.getVideo() != null) {
                                        DataTalkViewItemVO.File videoFile = BeanUtil.convertBean(dataTalkMsgBO.getVideo(), DataTalkViewItemVO.File.class);
                                        videoFile.setFileType(WxCpDataTalkMsgType.MSG_TYPE_VIDEO);
                                        if (StringUtils.isNotEmpty(videoFile.getFilePath())) {
                                            videoFile.setFilePath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), videoFile.getFilePath()));
                                        }
                                        dataTalkItemVO.setFile(videoFile);
                                        videoLists.add(videoFile);
                                    }
                                } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_FILE)) {
                                    if (dataTalkMsgBO.getFile() != null) {
                                        DataTalkViewItemVO.File attachFile = BeanUtil.convertBean(dataTalkMsgBO.getFile(), DataTalkViewItemVO.File.class);
                                        attachFile.setFileType(WxCpDataTalkMsgType.MSG_TYPE_FILE);
                                        if (StringUtils.isNotEmpty(attachFile.getFilePath())) {
                                            attachFile.setFilePath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), attachFile.getFilePath()));
                                        }
                                        dataTalkItemVO.setFile(attachFile);
                                        fileLists.add(attachFile);
                                    }
                                } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_LOCATION)) {
                                    if (dataTalkMsgBO.getLocation() != null) {
                                        DataTalkViewItemVO.Location location = BeanUtil.convertBean(dataTalkMsgBO.getLocation(), DataTalkViewItemVO.Location.class);
                                        dataTalkItemVO.setLocation(location);
                                    }
                                }
                            }
                        }
                        if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_REVOKE)) {
                            dataTalkItemVO.setIsRevoke(1);
                        } else {
                            dataTalkItemVO.setIsRevoke(0);
                        }
                        dataTalkLists.add(dataTalkItemVO);
                    }
                    dataTalkView.setDataTalkLists(dataTalkLists);
                    dataTalkView.setVideoLists(videoLists);
                    dataTalkView.setImageLists(imageLists);
                    dataTalkView.setVoiceLists(voiceLists);
                    dataTalkView.setFileLists(fileLists);
                }
                return dataTalkView;
            }
        }
        return null;
    }

    @Override
    public DataTalkViewVO queryByGroupCode(String groupCode){
        if(StringUtils.isEmpty(groupCode)) throw new BusinessException("群代码不能为空！");
        LambdaQueryWrapper<DataTalkFriendsDO> query = new LambdaQueryWrapper<>();
        query.eq(DataTalkFriendsDO::getType,3);
        query.eq(DataTalkFriendsDO::getRoomId,groupCode);
        query.orderByDesc(DataTalkFriendsDO::getMsgTime);
        List<DataTalkFriendsDO> dataTalkFriendsDOS = dataTalkFriendsMapper.selectList(query);
        if(Collections3.isNotEmpty(dataTalkFriendsDOS)) {
            DataTalkViewVO dataTalkViewVO = BeanUtil.convertBean(dataTalkFriendsDOS.get(0), DataTalkViewVO.class);
            List<DataTalkViewItemVO> dataTalkLists = new ArrayList<>();
            List<DataTalkViewItemVO.File> fileLists = new ArrayList<>();
            List<DataTalkViewItemVO.File> imageLists = new ArrayList<>();
            List<DataTalkViewItemVO.File> voiceLists = new ArrayList<>();
            List<DataTalkViewItemVO.File> videoLists = new ArrayList<>();
            List<DataTalkDO> entityDOS = dataTalkMapper.selectList(new LambdaQueryWrapper<DataTalkDO>().eq(DataTalkDO::getRoomId, groupCode).orderByDesc(DataTalkDO::getMsgTime));
            if (Collections3.isNotEmpty(entityDOS)) {
                for (DataTalkDO dataTalkDO : entityDOS) {
                    DataTalkViewItemVO dataTalkItemVO = BeanUtil.convertBean(dataTalkDO, DataTalkViewItemVO.class);
                    LocalDateTime createTime = dataTalkDO.getCreateTime();
                    if (createTime != null) {
                        dataTalkItemVO.setCreateTime(DateUtil.localDateTimeToStr(createTime));
                    }
                    LocalDateTime msgTime = dataTalkDO.getMsgTime();
                    if (msgTime != null) {
                        dataTalkItemVO.setMsgTime(DateUtil.localDateTimeToStr(msgTime));
                    }
                    DataTalkFriendsDO dataTalkFriendsDO = dataTalkFriendsDOS.stream().filter(d->d.getSender().equalsIgnoreCase(dataTalkDO.getSender())).findFirst().get();
                    if(dataTalkFriendsDO!=null) {
                        DataTalkViewVO dataTalkView = transferFriendsDOToViewVO(dataTalkFriendsDO);
                        dataTalkItemVO.setCode(dataTalkDO.getSender());
                        dataTalkItemVO.setName(dataTalkView.getSenderName());
                        dataTalkItemVO.setNickName(dataTalkView.getSenderNickName());
                        dataTalkItemVO.setAvatar(dataTalkView.getSenderAvatar());
                        dataTalkItemVO.setSide("left");
                    }else{
                        dataTalkFriendsDO = dataTalkFriendsDOS.stream().filter(d->d.getReceiver().equalsIgnoreCase(dataTalkDO.getSender())).findFirst().get();
                        if(dataTalkFriendsDO!=null) {
                            DataTalkViewVO dataTalkView = transferFriendsDOToViewVO(dataTalkFriendsDO);
                            dataTalkItemVO.setCode(dataTalkDO.getSender());
                            dataTalkItemVO.setName(dataTalkView.getSenderName());
                            dataTalkItemVO.setNickName(dataTalkView.getSenderNickName());
                            dataTalkItemVO.setAvatar(dataTalkView.getSenderAvatar());
                            dataTalkItemVO.setSide("left");
                        }
                    }

                    String content = dataTalkDO.getContent();
                    if (StringUtils.isNotEmpty(content)) {
                        DataTalkMsgBO dataTalkMsgBO = JsonUtils.fromJson(content, DataTalkMsgBO.class);
                        if (dataTalkMsgBO != null) {
                            if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_TEXT)) {
                                dataTalkItemVO.setMsgText(dataTalkMsgBO.getText().getContent());
                            } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_IMAGE)) {
                                if (dataTalkMsgBO.getImage() != null) {
                                    DataTalkViewItemVO.File imageFile = BeanUtil.convertBean(dataTalkMsgBO.getImage(), DataTalkViewItemVO.File.class);
                                    imageFile.setFileType(WxCpDataTalkMsgType.MSG_TYPE_IMAGE);
                                    if (StringUtils.isNotEmpty(imageFile.getFilePath())) {
                                        imageFile.setFilePath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), imageFile.getFilePath()));
                                    }
                                    dataTalkItemVO.setFile(imageFile);
                                    imageLists.add(imageFile);
                                }
                            } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_VOICE)) {
                                if (dataTalkMsgBO.getVoice() != null) {
                                    DataTalkViewItemVO.File voiceFile = BeanUtil.convertBean(dataTalkMsgBO.getVoice(), DataTalkViewItemVO.File.class);
                                    voiceFile.setFileType(WxCpDataTalkMsgType.MSG_TYPE_VOICE);
                                    if (StringUtils.isNotEmpty(voiceFile.getFilePath())) {
                                        voiceFile.setFilePath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), voiceFile.getFilePath()));
                                    }
                                    dataTalkItemVO.setFile(voiceFile);
                                    voiceLists.add(voiceFile);
                                }
                            } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_VIDEO)) {
                                if (dataTalkMsgBO.getVideo() != null) {
                                    DataTalkViewItemVO.File videoFile = BeanUtil.convertBean(dataTalkMsgBO.getVideo(), DataTalkViewItemVO.File.class);
                                    videoFile.setFileType(WxCpDataTalkMsgType.MSG_TYPE_VIDEO);
                                    if (StringUtils.isNotEmpty(videoFile.getFilePath())) {
                                        videoFile.setFilePath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), videoFile.getFilePath()));
                                    }
                                    dataTalkItemVO.setFile(videoFile);
                                    videoLists.add(videoFile);
                                }
                            } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_FILE)) {
                                if (dataTalkMsgBO.getFile() != null) {
                                    DataTalkViewItemVO.File attachFile = BeanUtil.convertBean(dataTalkMsgBO.getFile(), DataTalkViewItemVO.File.class);
                                    attachFile.setFileType(WxCpDataTalkMsgType.MSG_TYPE_FILE);
                                    if (StringUtils.isNotEmpty(attachFile.getFilePath())) {
                                        attachFile.setFilePath(UrlUtils.addUrlDomainName(fileOssProp.getHost(), attachFile.getFilePath()));
                                    }
                                    dataTalkItemVO.setFile(attachFile);
                                    fileLists.add(attachFile);
                                }
                            } else if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_LOCATION)) {
                                if (dataTalkMsgBO.getLocation() != null) {
                                    DataTalkViewItemVO.Location location = BeanUtil.convertBean(dataTalkMsgBO.getLocation(), DataTalkViewItemVO.Location.class);
                                    dataTalkItemVO.setLocation(location);
                                }
                            }
                        }
                    }
                    if (dataTalkDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_REVOKE)) {
                        dataTalkItemVO.setIsRevoke(1);
                    } else {
                        dataTalkItemVO.setIsRevoke(0);
                    }
                    dataTalkLists.add(dataTalkItemVO);
                }
                dataTalkViewVO.setDataTalkLists(dataTalkLists);
                dataTalkViewVO.setVideoLists(videoLists);
                dataTalkViewVO.setImageLists(imageLists);
                dataTalkViewVO.setVoiceLists(voiceLists);
                dataTalkViewVO.setFileLists(fileLists);
            }
            return dataTalkViewVO;

        }
        return null;
    }
    @Override
    public List<DataTalkFriendsViewVO> queryFriendsList(String code, Integer type) {
        if(StringUtils.isEmpty(code)) throw new BusinessException("员工代码不能为空！");
        List<DataTalkFriendsViewVO> friendsViewVOList = new ArrayList<>();
        LambdaQueryWrapper<DataTalkFriendsDO> query = new LambdaQueryWrapper<>();
        query.eq(DataTalkFriendsDO::getType,type);
        query.and(wq->wq.eq(DataTalkFriendsDO::getSender,code).or().eq(DataTalkFriendsDO::getReceiver,code));

        List<DataTalkFriendsDO> dataTalkFriendsDOS = dataTalkFriendsMapper.selectList(query);

        List<String> firendsCodeList = new ArrayList<>();
        if(Collections3.isNotEmpty(dataTalkFriendsDOS)){
            Map<String,List<DataTalkFriendsDO>> senderCodeMap = dataTalkFriendsDOS.stream().collect(Collectors.groupingBy(DataTalkFriendsDO::getSender));
            Map<String,List<DataTalkFriendsDO>> receiverCodeMap = dataTalkFriendsDOS.stream().collect(Collectors.groupingBy(DataTalkFriendsDO::getReceiver));

            List<String> senderCodeList = dataTalkFriendsDOS.stream().map(DataTalkFriendsDO::getSender).collect(Collectors.toList());
            firendsCodeList.addAll(senderCodeList);
            List<String> receiverCodeList = dataTalkFriendsDOS.stream().map(DataTalkFriendsDO::getReceiver).collect(Collectors.toList());
            firendsCodeList.addAll(receiverCodeList);

            List<String> distinctCodeList = firendsCodeList.stream().distinct().collect(Collectors.toList());
            distinctCodeList.remove(code);

            if(Collections3.isNotEmpty(distinctCodeList)){
                for(String friendsCode: distinctCodeList){
                    List<DataTalkFriendsDO> friendsDOS = senderCodeMap!=null?senderCodeMap.get(friendsCode):null;
                    if(Collections3.isNotEmpty(friendsDOS)) {
                        DataTalkFriendsDO friendsDO = friendsDOS.stream().sorted(Comparator.comparing(DataTalkFriendsDO::getMsgTime,Comparator.reverseOrder())).findFirst().get();
                        DataTalkFriendsViewVO friendsViewVO = BeanUtil.convertBean(friendsDO, DataTalkFriendsViewVO.class);
                        friendsViewVO.setEmployeeCode(code);
                        friendsViewVO.setFriendsCode(friendsDO.getSender());

                        friendsViewVO.setFriendsName(friendsDO.getSenderName());
                        friendsViewVO.setFriendsNickName(friendsDO.getSenderNickName());
                        if(StringUtils.isEmpty(friendsDO.getSenderName()) && StringUtils.isEmpty(friendsDO.getSenderNickName())){
                            friendsViewVO.setFriendsName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                            friendsViewVO.setFriendsNickName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                        }
                        String friendsAvatar = friendsDO.getSenderAvatar();
                        if(StringUtils.isNotEmpty(friendsAvatar)) {
                            friendsAvatar = UrlUtils.addUrlDomainName(fileOssProp.getHost(), friendsAvatar);
                            friendsViewVO.setFriendsAvatar(friendsAvatar);
                        }else{
                            friendsAvatar = UrlUtils.addUrlDomainName(fileOssProp.getHost(), DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE);
                            friendsViewVO.setFriendsAvatar(friendsAvatar);
                        }
                        LocalDateTime msgTime = friendsDO.getMsgTime();
                        if(msgTime!=null){
                            friendsViewVO.setMsgTime(DateUtil.localDateTimeToStr(msgTime));
                        }
                        if(friendsDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_TEXT)){
                            friendsViewVO.setLastContent(friendsDO.getTextContent());
                            friendsViewVO.setMsgTip("");
                        }else{
                            friendsViewVO.setLastContent("");
                            friendsViewVO.setMsgTip(DataTalkMsgTipEnum.getDescByCode(friendsDO.getMsgType()));
                        }
                        friendsViewVOList.add(friendsViewVO);
                    }else {
                        friendsDOS = receiverCodeMap!=null?receiverCodeMap.get(friendsCode):null;
                        if(Collections3.isNotEmpty(friendsDOS)) {
                            DataTalkFriendsDO friendsDO = friendsDOS.stream().sorted(Comparator.comparing(DataTalkFriendsDO::getMsgTime,Comparator.reverseOrder())).findFirst().get();
                            DataTalkFriendsViewVO friendsViewVO = BeanUtil.convertBean(friendsDO, DataTalkFriendsViewVO.class);
                            friendsViewVO.setEmployeeCode(code);
                            friendsViewVO.setFriendsCode(friendsDO.getReceiver());
                            friendsViewVO.setFriendsName(friendsDO.getReceiverName());
                            friendsViewVO.setFriendsNickName(friendsDO.getReceiverNickName());
                            if(StringUtils.isEmpty(friendsDO.getReceiverName()) && StringUtils.isEmpty(friendsDO.getReceiverNickName())){
                                friendsViewVO.setFriendsName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                                friendsViewVO.setFriendsNickName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                            }
                            String friendsAvatar = friendsDO.getReceiverAvatar();
                            if(StringUtils.isNotEmpty(friendsAvatar)) {
                                friendsAvatar = UrlUtils.addUrlDomainName(fileOssProp.getHost(), friendsAvatar);
                                friendsViewVO.setFriendsAvatar(friendsAvatar);
                            }else{
                                friendsAvatar = UrlUtils.addUrlDomainName(fileOssProp.getHost(), DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE);
                                friendsViewVO.setFriendsAvatar(friendsAvatar);
                            }
                            LocalDateTime msgTime = friendsDO.getMsgTime();
                            if(msgTime!=null){
                                friendsViewVO.setMsgTime(DateUtil.localDateTimeToStr(msgTime));
                            }
                            if(friendsDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_TEXT)){
                                friendsViewVO.setLastContent(friendsDO.getTextContent());
                                friendsViewVO.setMsgTip("");
                            }else{
                                friendsViewVO.setLastContent("");
                                friendsViewVO.setMsgTip(DataTalkMsgTipEnum.getDescByCode(friendsDO.getMsgType()));
                            }
                            friendsViewVOList.add(friendsViewVO);
                        }
                    }
                }
            }
        }

        return friendsViewVOList;
    }

    @Override
    public List<DataTalkFriendsViewVO> queryGroupList(String code) {
        if(StringUtils.isEmpty(code)) throw new BusinessException("员工代码不能为空！");
        List<DataTalkFriendsViewVO> friendsViewVOList = new ArrayList<>();
        LambdaQueryWrapper<DataTalkFriendsDO> query = new LambdaQueryWrapper<>();
        query.eq(DataTalkFriendsDO::getType,3);
        query.isNotNull(DataTalkFriendsDO::getRoomId);
        query.and(wq->wq.eq(DataTalkFriendsDO::getSender,code).or().eq(DataTalkFriendsDO::getReceiver,code));
        LogUtils.info(">>>>>>>query:{}",query.getTargetSql());
        List<DataTalkFriendsDO> dataTalkFriendsDOS = dataTalkFriendsMapper.selectList(query);

        if(Collections3.isNotEmpty(dataTalkFriendsDOS)){
            Map<String,List<DataTalkFriendsDO>> roomIdMap = dataTalkFriendsDOS.stream().collect(Collectors.groupingBy(DataTalkFriendsDO::getRoomId));

            List<String> roomIdList = dataTalkFriendsDOS.stream().map(DataTalkFriendsDO::getRoomId).collect(Collectors.toList());
            List<String> distinctRoomIdList = Collections3.isNotEmpty(roomIdList)?roomIdList.stream().distinct().collect(Collectors.toList()):null;

            if(Collections3.isNotEmpty(distinctRoomIdList)){
                for(String roomId: distinctRoomIdList){
                    List<DataTalkFriendsDO> friendsDOS = roomIdMap!=null?roomIdMap.get(roomId):null;
                    if(Collections3.isNotEmpty(friendsDOS)) {
                        DataTalkFriendsDO friendsDO = friendsDOS.stream().sorted(Comparator.comparing(DataTalkFriendsDO::getMsgTime, Comparator.reverseOrder())).findFirst().get();
                        DataTalkFriendsViewVO friendsViewVO = BeanUtil.convertBean(friendsDO, DataTalkFriendsViewVO.class);
                        friendsViewVO.setRoomId(roomId);
                        friendsViewVO.setRoomName(StringUtils.isNotEmpty(friendsDO.getRoomName())?friendsDO.getRoomName():FriendsConstant.ANONYMOUS_GROUP_NAME);
                        friendsViewVO.setFriendsCode(friendsDO.getSender());
                        friendsViewVO.setFriendsName(friendsDO.getSenderName());
                        friendsViewVO.setFriendsNickName(friendsDO.getSenderNickName());
                        if(StringUtils.isEmpty(friendsDO.getSenderName()) && StringUtils.isEmpty(friendsDO.getSenderNickName())){
                            friendsViewVO.setFriendsName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                            friendsViewVO.setFriendsNickName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
                        }
                        String friendsAvatar = friendsDO.getSenderAvatar();
                        if(StringUtils.isNotEmpty(friendsAvatar)) {
                            friendsAvatar = UrlUtils.addUrlDomainName(fileOssProp.getHost(), friendsAvatar);
                            friendsViewVO.setFriendsAvatar(friendsAvatar);
                        }else{
                            friendsAvatar = UrlUtils.addUrlDomainName(fileOssProp.getHost(), DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE);
                            friendsViewVO.setFriendsAvatar(friendsAvatar);
                        }
                        LocalDateTime msgTime = friendsDO.getMsgTime();
                        if(msgTime!=null){
                            friendsViewVO.setMsgTime(DateUtil.localDateTimeToStr(msgTime));
                        }
                        if(friendsDO.getMsgType().equalsIgnoreCase(WxCpDataTalkMsgType.MSG_TYPE_TEXT)){
                            friendsViewVO.setLastContent(friendsDO.getTextContent());
                            friendsViewVO.setMsgTip("");
                        }else{
                            friendsViewVO.setLastContent("");
                            friendsViewVO.setMsgTip(DataTalkMsgTipEnum.getDescByCode(friendsDO.getMsgType()));
                        }
                        friendsViewVOList.add(friendsViewVO);
                    }
                }
            }
        }

        return friendsViewVOList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(DataTalkParam param) {
        DataTalkDO entityDO = BeanUtil.convertBean(param, DataTalkDO.class);
        entityDO.setId(GenerateId.generateId());
        entityDO.setCreateTime(LocalDateTime.now());
        return dataTalkMapper.insert(entityDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateFriendsAgree(String employeeCode, String friendsCode, String welcomeCode){
        if(StringUtils.isNotEmpty(employeeCode) && StringUtils.isNotEmpty(friendsCode)) {
            DataTalkFriendsAgreeDO friendsAgreeDO = dataTalkFriendsAgreeMapper.selectOne(new LambdaQueryWrapper<DataTalkFriendsAgreeDO>()
                    .eq(DataTalkFriendsAgreeDO::getEmployeeCode, employeeCode).eq(DataTalkFriendsAgreeDO::getFriendsOpenid, friendsCode));
            if(friendsAgreeDO!=null){
                friendsAgreeDO.setAgreeStatus(WxCpDataTalkFriendsAgreeEnum.FRIEND_AGREE.getCode());
            }
            if(StringUtils.isNotEmpty(welcomeCode)){
                friendsAgreeDO.setWelcomeCode(welcomeCode);
            }
            dataTalkFriendsAgreeMapper.updateById(friendsAgreeDO);
        }
        return true;
    }

    @Override
    public DataTalkVO view(Long id) {
        DataTalkDO entityDO = dataTalkMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        DataTalkVO entityVO = BeanUtil.convertBean(entityDO, DataTalkVO.class);
        return entityVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean syncBatchDataTalkFriendsAgreeFromWxCp(Long tenantId){
        try {
            WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId);
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }
            WxCpMsgAuditService wxCpMsgAuditService = wxCpService.getMsgAuditService();
            if(wxCpMsgAuditService == null)  throw new BusinessException("获取企微会话存档服务异常!");
            List<DataTalkFriendsAgreeDO> dataTalkFriendsAgreeDOList = new ArrayList<>();
            List<CopEmployeeDO> copEmployeeDOList = copEmployeeMapper.selectList(new LambdaQueryWrapper<>());
            List<FriendsDO> friendsDOList = friendsMapper.selectList(new LambdaQueryWrapper<>());
            List<String> employeeCodes = Collections3.isNotEmpty(copEmployeeDOList)?copEmployeeDOList.stream().filter(d->StringUtils.isNotEmpty(d.getEmployeeCode())).map(CopEmployeeDO::getEmployeeCode).collect(Collectors.toList()):null;
            List<String> friendsCodes = Collections3.isNotEmpty(friendsDOList)?friendsDOList.stream().filter(d->StringUtils.isNotEmpty(d.getFriendsCode())).map(FriendsDO::getFriendsCode).collect(Collectors.toList()):null;

            List<WxCpCheckAgreeRequest.Info>  checkAgreeRequestInfos = new ArrayList<>();
            if(Collections3.isNotEmpty(employeeCodes) && Collections3.isNotEmpty(friendsCodes)){
                employeeCodes.stream().forEach(d->{
                    friendsCodes.stream().forEach(f->{
                        WxCpCheckAgreeRequest.Info checkAgreeRequestInfo = new WxCpCheckAgreeRequest.Info();
                        checkAgreeRequestInfo.setUserid(d);
                        checkAgreeRequestInfo.setExteranalOpenId(f);
                        checkAgreeRequestInfos.add(checkAgreeRequestInfo);
                    });
                });
            }
            List<List<WxCpCheckAgreeRequest.Info>> groupCheckAgreeRequestInfos = ListUtils.partition(checkAgreeRequestInfos, 90);

            if(Collections3.isNotEmpty(groupCheckAgreeRequestInfos)) {
                for(List<WxCpCheckAgreeRequest.Info> agreeRequestInfoList:groupCheckAgreeRequestInfos) {
                    WxCpCheckAgreeRequest checkAgreeRequest = new WxCpCheckAgreeRequest();
                    checkAgreeRequest.setInfo(agreeRequestInfoList);
                    WxCpAgreeInfo wxCpAgreeInfo = wxCpMsgAuditService.checkSingleAgree(checkAgreeRequest);
                    if (wxCpAgreeInfo != null) {
                        List<WxCpAgreeInfo.AgreeInfo> agreeInfoList = wxCpAgreeInfo.getAgreeInfo();
                        if (Collections3.isNotEmpty(agreeInfoList)) {
                            for (WxCpAgreeInfo.AgreeInfo agreeInfo : agreeInfoList) {
                                DataTalkFriendsAgreeDO friendsAgreeDO = new DataTalkFriendsAgreeDO();
                                Long id = IdGenerator.getId();
                                friendsAgreeDO.setId(id);
                                friendsAgreeDO.setEmployeeCode(agreeInfo.getUserid());
                                friendsAgreeDO.setFriendsOpenid(agreeInfo.getExteranalOpenId());
                                friendsAgreeDO.setAgreeStatus(agreeInfo.getAgreeStatus());
                                Long statusChangeTime = agreeInfo.getStatusChangeTime();
                                if (statusChangeTime != null) {
                                    friendsAgreeDO.setChangeTime(DateUtil.longToLocalDateTime(statusChangeTime));
                                }
                                friendsAgreeDO.setCreateTime(LocalDateTime.now());
                                dataTalkFriendsAgreeDOList.add(friendsAgreeDO);
                            }
                        }
                    }
                }
            }
            if(Collections3.isNotEmpty(dataTalkFriendsAgreeDOList)){
                dataTalkFriendsAgreeMapper.insertBatchSomeColumn(dataTalkFriendsAgreeDOList);
            }
            return true;
        } catch (Exception e) {
            LogUtils.error("同步会话同意情况处理异常:{}", e);
            return false;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean syncBatchDataTalkFriendsPermitFromWxCp(Long tenantId){
        try {
            WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId);
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }
            WxCpMsgAuditService wxCpMsgAuditService = wxCpService.getMsgAuditService();
            if(wxCpMsgAuditService == null)  throw new BusinessException("获取企微会话存档服务异常!");
            List<DataTalkFriendsPermitDO> dataTalkGroupDOList = new ArrayList<>();
            for(WxCpDataTalkFriendsPermitEnum enumObj: WxCpDataTalkFriendsPermitEnum.values()) {
                Integer type =  enumObj.getCode();
                List<String> friendsList = wxCpMsgAuditService.getPermitUserList(type);

                if(Collections3.isNotEmpty(friendsList)){
                    for (String friendsCode: friendsList) {
                        DataTalkFriendsPermitDO friendsPermitDO = new DataTalkFriendsPermitDO();
                        Long id = IdGenerator.getId();
                        friendsPermitDO.setId(id);
                        friendsPermitDO.setType(type);
                        friendsPermitDO.setFriendsCode(friendsCode);
                        friendsPermitDO.setCreateTime(LocalDateTime.now());
                        dataTalkGroupDOList.add(friendsPermitDO);
                    }
                }
            }
            if(Collections3.isNotEmpty(dataTalkGroupDOList)){
                dataTalkFriendsPermitMapper.insertBatchSomeColumn(dataTalkGroupDOList);
            }
            return true;
        } catch (Exception e) {
            LogUtils.error("同步会话内容存档开启成员列表处理异常:{}", e);
            return false;
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean syncBatchDataTalkFromWxCp(Long tenantId){
        try {
            WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId);
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }
            WxCpMsgAuditService wxCpMsgAuditService = wxCpService.getMsgAuditService();
            if(wxCpMsgAuditService == null)  throw new BusinessException("获取企微会话存档服务异常!");
            List<DataTalkDO> dataTalkDOList = new ArrayList<>();
            List<DataTalkFriendsDO> dataTalkFriendsDOList = new ArrayList<>();
            List<String> mediaType = Arrays.asList(WxCpDataTalkMsgType.MSG_TYPE_TEXT,WxCpDataTalkMsgType.MSG_TYPE_IMAGE,
                    WxCpDataTalkMsgType.MSG_TYPE_VOICE,WxCpDataTalkMsgType.MSG_TYPE_VIDEO,WxCpDataTalkMsgType.MSG_TYPE_EMOTION,
                    WxCpDataTalkMsgType.MSG_TYPE_FILE,WxCpDataTalkMsgType.MSG_TYPE_MEETING_VOICE_CALL,WxCpDataTalkMsgType.MSG_TYPE_LOCATION,
                    WxCpDataTalkMsgType.MSG_TYPE_VOIP_DOC_SHARE,WxCpDataTalkMsgType.MSG_TYPE_LINK);

            Long msgSeq = redisUtils.getLong(RedisKeyConstant.WX_CP_DATA_TALK_SEQ.concat(tenantId.toString()));
            if(msgSeq == null){
                QueryWrapper query = new QueryWrapper<DataTalkDO>();
                query.select("  IFNULL( max(msg_seq),2) as maxSeq ");
                Map<String, Long> seqMap = super.getMap(query);
                msgSeq = seqMap!=null?seqMap.get("maxSeq"):2L;
            }
            List<CopEmployeeDO> copEmployeeDOS = copEmployeeMapper.selectList(new LambdaQueryWrapper<CopEmployeeDO>());
            Map<String, CopEmployeeDO> copEmployeeMap = Collections3.isNotEmpty(copEmployeeDOS)?copEmployeeDOS.stream().collect(Collectors.toMap(CopEmployeeDO::getEmployeeCode, x->x, (o, n) -> n)):null;
            List<FriendsDO> friendsDOS = friendsMapper.selectList(new LambdaQueryWrapper<FriendsDO>());
            Map<String, FriendsDO> friendsMap = Collections3.isNotEmpty(friendsDOS)?friendsDOS.stream().collect(Collectors.toMap(FriendsDO::getFriendsCode, x->x, (o, n) -> n)):null;
            List<GroupDO> groupDOS = groupMapper.selectList(new LambdaQueryWrapper<GroupDO>());
            Map<String, String> groupNameMap = Collections3.isNotEmpty(groupDOS)?groupDOS.stream().collect(Collectors.toMap(GroupDO::getChatId, GroupDO::getName, (o, n) -> n)):null;
            Boolean isLastRecord = false;
            do {
                WxCpChatDatas wxCpChatDatas = wxCpMsgAuditService.getChatDatas(msgSeq, 900L, null, null, 1000L);
                if (wxCpChatDatas != null && wxCpChatDatas.getChatData().size() > 0) {
                    List<WxCpChatDatas.WxCpChatData> chatDataList = wxCpChatDatas.getChatData();
                    Iterator<WxCpChatDatas.WxCpChatData> chatDataIterator = chatDataList.iterator();
                    while (chatDataIterator.hasNext()) {
                        WxCpChatDatas.WxCpChatData wxCpChatData = chatDataIterator.next();
                        if(msgSeq == wxCpChatData.getSeq()) {
                            isLastRecord = true;
                            redisUtils.set(RedisKeyConstant.WX_CP_DATA_TALK_SEQ.concat(tenantId.toString()), msgSeq);
                            break;
                        }
                        msgSeq = wxCpChatData.getSeq();

                        final WxCpChatModel decryptData = wxCpMsgAuditService.getDecryptData(wxCpChatDatas.getSdk(), wxCpChatData, 1);
                        if(decryptData!=null) {
                            LogUtils.info(">>>>>>>decryptData:{}", JsonUtils.toJsonStr(decryptData));
                            DataTalkDO dataTalkDO = new DataTalkDO();
                            Long talkId = IdGenerator.getId();
                            dataTalkDO.setId(talkId);
                            dataTalkDO.setMsgSeq(msgSeq);
                            dataTalkDO.setCreateTime(LocalDateTime.now());
                            String msgId = decryptData.getMsgId();
                            dataTalkDO.setMsgId(msgId);
                            dataTalkDO.setAction(StringUtils.isNotEmpty(decryptData.getAction())?decryptData.getAction():null);
                            dataTalkDO.setSend(StringUtils.isNotEmpty(decryptData.getSend())?decryptData.getSend():null);
                            String sender = decryptData.getFrom();
                            dataTalkDO.setSender(sender);
                            String roomId = decryptData.getRoomId();
                            dataTalkDO.setRoomId(roomId);
                            Long rtnMsgTime = decryptData.getMsgTime();
                            String locaMsgDateTime = "";
                            if(rtnMsgTime!=null){
                                SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMATTER);
                                dateFormat.setTimeZone(TimeZone.getDefault());
                                locaMsgDateTime = dateFormat.format(new Date(rtnMsgTime));
                                dataTalkDO.setMsgTime(DateUtil.strToLocalDateTime(locaMsgDateTime));
                            }
                            String msgType = decryptData.getMsgType();
                            dataTalkDO.setMsgType(msgType);
                            String[] toList = decryptData.getTolist();
                            if(toList!=null && toList.length>0) {
                                dataTalkDO.setTolist(JsonUtils.toJsonStr(toList));
                                for(String receiver:toList){
                                  DataTalkFriendsDO dataTalkFriends = new DataTalkFriendsDO();
                                    dataTalkFriends.setId(IdGenerator.getId());
                                    dataTalkFriends.setCreateTime(LocalDateTime.now());
                                    dataTalkFriends.setTalkId(talkId);
                                    dataTalkFriends.setMsgSeq(msgSeq);
                                    dataTalkFriends.setMsgId(decryptData.getMsgId());
                                    dataTalkFriends.setMsgType(msgType);
                                    FriendsDO friendsDO = friendsMap!=null?friendsMap.get(sender):null;
                                    CopEmployeeDO copEmployee = copEmployeeMap!=null?copEmployeeMap.get(sender):null;
                                    if(StringUtils.isNotEmpty(sender)  && (sender.startsWith("wm") || sender.startsWith("wo") || sender.startsWith("wb"))) {
                                        String senderName = friendsDO!=null?friendsDO.getName():"";
                                        String senderNickName = friendsDO!=null?friendsDO.getNickname():"";
                                        String senderAvatar = friendsDO!=null?friendsDO.getAvatar(): DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE;
                                        dataTalkFriends.setSender(sender);
                                        dataTalkFriends.setSenderName(senderName);
                                        dataTalkFriends.setSenderNickName(senderNickName);
                                        dataTalkFriends.setSenderAvatar(senderAvatar);
                                    }else{
                                        String senderName = copEmployee!=null?copEmployee.getEmployeeName():"";
                                        String senderNickName = copEmployee!=null?copEmployee.getEmployeeName():"";
                                        String senderAvatar = copEmployee!=null?copEmployee.getAvatar(): DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE;
                                        dataTalkFriends.setSender(sender);
                                        dataTalkFriends.setSenderName(senderName);
                                        dataTalkFriends.setSenderNickName(senderNickName);
                                        dataTalkFriends.setSenderAvatar(senderAvatar);
                                    }
                                    if(StringUtils.isNotEmpty(receiver)  && (receiver.startsWith("wm") || receiver.startsWith("wo") || receiver.startsWith("wb"))){
                                        String receiverName = friendsDO!=null?friendsDO.getName():"";
                                        String receiverNickName = friendsDO!=null?friendsDO.getNickname():"";
                                        String receiverAvatar = friendsDO!=null?friendsDO.getAvatar(): DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE;
                                        dataTalkFriends.setReceiver(receiver);
                                        dataTalkFriends.setReceiverName(receiverName);
                                        dataTalkFriends.setReceiverNickName(receiverNickName);
                                        dataTalkFriends.setReceiverAvatar(receiverAvatar);
                                    }else{
                                        String receiverName = copEmployee!=null?copEmployee.getEmployeeName():"";
                                        String receiverNickName = copEmployee!=null?copEmployee.getEmployeeName():"";
                                        String receiverAvatar = copEmployee!=null?copEmployee.getAvatar(): DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE;
                                        dataTalkFriends.setReceiver(receiver);
                                        dataTalkFriends.setReceiverName(receiverName);
                                        dataTalkFriends.setReceiverNickName(receiverNickName);
                                        dataTalkFriends.setReceiverAvatar(receiverAvatar);
                                    }
                                    if(StringUtils.isNotEmpty(roomId)){
                                        dataTalkFriends.setRoomId(roomId);
                                        dataTalkFriends.setType(3);
                                        dataTalkFriends.setRoomName(groupNameMap!=null?groupNameMap.get(roomId):"");
                                    }else {
                                        if ((sender.startsWith("wm") || sender.startsWith("wo") || sender.startsWith("wb") ||
                                                receiver.startsWith("wm") || receiver.startsWith("wo") || receiver.startsWith("wb"))) {
                                            dataTalkFriends.setType(2);
                                        } else {
                                            dataTalkFriends.setType(1);
                                        }
                                    }
                                    if(StringUtils.isNotEmpty(locaMsgDateTime)){
                                        dataTalkFriends.setMsgTime(DateUtil.strToLocalDateTime(locaMsgDateTime));
                                    }
                                    if(WxCpDataTalkMsgType.MSG_TYPE_TEXT.equalsIgnoreCase(decryptData.getMsgType())){
                                        String content = decryptData.getText().getContent();
                                        dataTalkFriends.setTextContent(content);
                                    }
                                    dataTalkFriendsDOList.add(dataTalkFriends);
                                }
                            }

                            if (mediaType.contains(decryptData.getMsgType())) {
                                DataTalkMsgBO msgContent = new DataTalkMsgBO();
                                String suffix = "";  // 文件后缀
                                String md5Sum = "";  // 文件名md5
                                String sdkFileId = "";  // sdkFileId
                                switch (msgType) {
                                    case WxCpDataTalkMsgType.MSG_TYPE_TEXT: {
                                        String content = decryptData.getText().getContent();
                                        DataTalkMsgBO.Text text = new DataTalkMsgBO.Text();
                                        text.setContent(content);
                                        msgContent.setText(text);
                                        break;
                                    }
                                    case WxCpDataTalkMsgType.MSG_TYPE_IMAGE: {
                                        suffix = WxCpDataTalkMediaSuffix.JPG;
                                        md5Sum = decryptData.getImage().getMd5Sum();
                                        sdkFileId = decryptData.getImage().getSdkFileId();
                                        Long fileSize = decryptData.getImage().getFileSize();
                                        String fileName = md5Sum.concat(suffix);
                                        String targetPath = fileConfigProp.getFilePath().concat("/").concat(fileName);
                                        wxCpMsgAuditService.getMediaFile(wxCpChatDatas.getSdk(), sdkFileId, null, null, 1000L, targetPath);
                                        String ossPath = uploadLocalFileToOss(targetPath, md5Sum + suffix);
                                        DataTalkMsgBO.Image image = new DataTalkMsgBO.Image();
                                        image.setFileName(fileName);
                                        image.setFilePath(ossPath);
                                        image.setFileSize(fileSize);
                                        msgContent.setImage(image);
                                        break;
                                    }
                                    case WxCpDataTalkMsgType.MSG_TYPE_VOICE: {
                                        suffix = WxCpDataTalkMediaSuffix.AMR;
                                        md5Sum = decryptData.getVoice().getMd5Sum();
                                        sdkFileId = decryptData.getVoice().getSdkFileId();
                                        Long voiceSize = decryptData.getVoice().getVoiceSize();
                                        Long palyLength = decryptData.getVoice().getPlayLength();
                                        String fileName = md5Sum.concat(suffix);
                                        String targetPath = fileConfigProp.getFilePath().concat("/").concat(fileName);
                                        wxCpMsgAuditService.getMediaFile(wxCpChatDatas.getSdk(), sdkFileId, null, null, 1000L, targetPath);
                                        String ossPath = uploadLocalFileToOss(targetPath, md5Sum + suffix);
                                        DataTalkMsgBO.Voice voice = new DataTalkMsgBO.Voice();
                                        voice.setFileName(fileName);
                                        voice.setFilePath(ossPath);
                                        voice.setFileSize(voiceSize);
                                        voice.setPlayLength(palyLength);
                                        msgContent.setVoice(voice);
                                        break;
                                    }
                                    case WxCpDataTalkMsgType.MSG_TYPE_VIDEO: {
                                        suffix = WxCpDataTalkMediaSuffix.MP4;
                                        md5Sum = decryptData.getVideo().getMd5Sum();
                                        sdkFileId = decryptData.getVideo().getSdkFileId();
                                        Long fileSize = decryptData.getVideo().getFileSize();
                                        Long palyLength = decryptData.getVideo().getPlayLength();
                                        String fileName = md5Sum.concat(suffix);
                                        String targetPath = fileConfigProp.getFilePath().concat("/").concat(fileName);
                                        wxCpMsgAuditService.getMediaFile(wxCpChatDatas.getSdk(), sdkFileId, null, null, 1000L, targetPath);
                                        String ossPath = uploadLocalFileToOss(targetPath, md5Sum + suffix);
                                        DataTalkMsgBO.Video video = new DataTalkMsgBO.Video();
                                        video.setFileName(fileName);
                                        video.setFilePath(ossPath);
                                        video.setFileSize(fileSize);
                                        video.setPlayLength(palyLength);
                                        msgContent.setVideo(video);
                                        break;
                                    }
                                    case WxCpDataTalkMsgType.MSG_TYPE_EMOTION: {
                                        md5Sum = decryptData.getEmotion().getMd5Sum();
                                        sdkFileId = decryptData.getEmotion().getSdkFileId();
                                        int type = decryptData.getEmotion().getType();
                                        switch (type) {
                                            case 1: {
                                                suffix = WxCpDataTalkMediaSuffix.GIF;
                                                String fileName = md5Sum.concat(suffix);
                                                String targetPath = fileConfigProp.getFilePath().concat("/").concat(fileName);
                                                wxCpMsgAuditService.getMediaFile(wxCpChatDatas.getSdk(), sdkFileId, null, null, 1000L, targetPath);
                                                String ossPath = uploadLocalFileToOss(targetPath, md5Sum + suffix);
                                                DataTalkMsgBO.Emotion emotion = new DataTalkMsgBO.Emotion();
                                                emotion.setFileName(fileName);
                                                emotion.setFilePath(ossPath);
                                                msgContent.setEmotion(emotion);
                                                break;
                                            }
                                            case 2: {
                                                suffix = WxCpDataTalkMediaSuffix.PNG;
                                                String fileName = md5Sum.concat(suffix);
                                                String targetPath = fileConfigProp.getFilePath().concat("/").concat(fileName);
                                                wxCpMsgAuditService.getMediaFile(wxCpChatDatas.getSdk(), sdkFileId, null, null, 1000L, targetPath);
                                                String ossPath = uploadLocalFileToOss(targetPath, md5Sum + suffix);
                                                DataTalkMsgBO.Emotion emotion = new DataTalkMsgBO.Emotion();
                                                emotion.setFileName(fileName);
                                                emotion.setFilePath(ossPath);
                                                msgContent.setEmotion(emotion);
                                                break;
                                            }
                                        }
                                        break;
                                    }
                                    case WxCpDataTalkMsgType.MSG_TYPE_FILE: {
                                        md5Sum = decryptData.getFile().getMd5Sum();
                                        suffix = "." + decryptData.getFile().getFileExt();
                                        sdkFileId = decryptData.getFile().getSdkFileId();
                                        Integer fileSize = decryptData.getFile().getFileSize();
                                        String fileRealName = decryptData.getFile().getFileName();
                                        String fileName = md5Sum.concat(suffix);
                                        String targetPath = fileConfigProp.getFilePath().concat("/").concat(fileName);
                                        wxCpMsgAuditService.getMediaFile(wxCpChatDatas.getSdk(), sdkFileId, null, null, 1000L, targetPath);
                                        String ossPath = uploadLocalFileToOss(targetPath, md5Sum + suffix);
                                        DataTalkMsgBO.File file = new DataTalkMsgBO.File();
                                        file.setFileName(fileName);
                                        file.setFileRealName(fileRealName);
                                        file.setFileExt(suffix);
                                        file.setFileSize(fileSize);
                                        file.setFilePath(ossPath);
                                        msgContent.setFile(file);
                                        break;
                                    }
                                    // link消息
                                    case WxCpDataTalkMsgType.MSG_TYPE_LINK: {
                                        DataTalkMsgBO.Link link  = BeanUtil.convertBean(decryptData.getLink(), DataTalkMsgBO.Link.class);
                                        String imageUrl = link.getImageUrl();
                                        if(StringUtils.isNotEmpty(imageUrl)){
                                            imageUrl = transferFileToOss(tenantId.toString(), imageUrl);
                                            link.setImageUrl(imageUrl);
                                        }
                                        msgContent.setLink(link);
                                        break;
                                    }
                                    // 音频存档消息
                                    case WxCpDataTalkMsgType.MSG_TYPE_MEETING_VOICE_CALL: {
                                        md5Sum = decryptData.getVoiceId();
                                        sdkFileId = decryptData.getMeetingVoiceCall().getSdkFileId();
                                        for (WxCpChatModel.MeetingVoiceCall.DemoFileData demofiledata :
                                                decryptData.getMeetingVoiceCall().getDemoFileData()) {
                                            String demoFileDataFileName = demofiledata.getFileName();
                                            suffix = demoFileDataFileName.substring(demoFileDataFileName.lastIndexOf(".") + 1);
                                        }
                                        break;
                                    }
                                    // 音频共享文档消息
                                    case WxCpDataTalkMsgType.MSG_TYPE_VOIP_DOC_SHARE: {
                                        md5Sum = decryptData.getVoipId();
                                        WxCpFileItem docShare = decryptData.getVoipDocShare();
                                        String fileName = docShare.getFileName();
                                        suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
                                        String fileFullName = md5Sum.concat(suffix);
                                        String targetPath = fileConfigProp.getFilePath().concat("/").concat(fileFullName);
                                        wxCpMsgAuditService.getMediaFile(wxCpChatDatas.getSdk(), sdkFileId, null, null, 1000L, targetPath);
                                        String ossPath = uploadLocalFileToOss(targetPath, md5Sum + suffix);
                                        DataTalkMsgBO.VoipDocShare voipDocShare = new DataTalkMsgBO.VoipDocShare();
                                        voipDocShare.setFileName(fileFullName);
                                        voipDocShare.setFilePath(ossPath);
                                        msgContent.setVoipDocShare(voipDocShare);
                                        break;
                                    }
                                    // 位置消息
                                    case WxCpDataTalkMsgType.MSG_TYPE_LOCATION: {
                                        DataTalkMsgBO.Location locaton = BeanUtil.convertBean(decryptData.getLocation(), DataTalkMsgBO.Location.class);
                                        msgContent.setLocation(locaton);
                                        break;
                                    }
                                }
                                if(msgContent!=null) {
                                    dataTalkDO.setContent(JsonUtils.toJsonStr(msgContent));
                                    dataTalkDOList.add(dataTalkDO);
                                }
                            }
                        }
                    }
                }
                Finance.DestroySdk(wxCpChatDatas.getSdk());
            }while(isLastRecord);
            LogUtils.info(">>>>>>>>>dataTalkDOList:{}",JsonUtils.toJsonStr(dataTalkDOList));
            if(Collections3.isNotEmpty(dataTalkDOList)){
                 dataTalkMapper.insertBatchSomeColumn(dataTalkDOList);
            }
            if(Collections3.isNotEmpty(dataTalkFriendsDOList)){
                dataTalkFriendsMapper.insertBatchSomeColumn(dataTalkFriendsDOList);
            }
            return true;
        } catch (Exception e) {
            LogUtils.error("同步会话内容存档处理异常:{}", e);
            return false;
        }
    }

    private DataTalkViewVO transferFriendsDOToViewVO(DataTalkFriendsDO dataTalkFriendsDO){
        DataTalkViewVO dataTalkView = BeanUtil.convertBean(dataTalkFriendsDO, DataTalkViewVO.class);
        if (StringUtils.isEmpty(dataTalkFriendsDO.getSenderName()) && StringUtils.isEmpty(dataTalkFriendsDO.getSenderNickName())) {
            dataTalkView.setSenderName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
            dataTalkView.setSenderNickName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
        }
        if (StringUtils.isEmpty(dataTalkFriendsDO.getReceiverName()) && StringUtils.isEmpty(dataTalkFriendsDO.getReceiverNickName())) {
            dataTalkView.setReceiverName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
            dataTalkView.setReceiverNickName(FriendsConstant.ANONYMOUS_FRIENDS_NAME);
        }
        if (StringUtils.isNotEmpty(dataTalkFriendsDO.getSenderAvatar())) {
            dataTalkView.setSenderAvatar(UrlUtils.addUrlDomainName(fileOssProp.getHost(), dataTalkFriendsDO.getSenderAvatar()));
        } else {
            dataTalkView.setSenderAvatar(UrlUtils.addUrlDomainName(fileOssProp.getHost(), DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE));
        }
        if (StringUtils.isNotEmpty(dataTalkFriendsDO.getReceiverAvatar())) {
            dataTalkView.setReceiverAvatar(UrlUtils.addUrlDomainName(fileOssProp.getHost(), dataTalkFriendsDO.getReceiverAvatar()));
        } else {
            dataTalkView.setReceiverAvatar(UrlUtils.addUrlDomainName(fileOssProp.getHost(), DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE));
        }
        return dataTalkView;
    }

    private String transferFileToOss(String tenantId, String fileUrl){
        try {
            String fileName = (String.valueOf(System.currentTimeMillis())).concat("_".concat(tenantId).concat(".png"));
            OssPolicyDto policy = OssService.policy();
            String fileTag = policy.getDir() + fileName;
            MultipartFile multipartFile = FileUtils.getMultipartFile(fileUrl, fileName, fileTag);
            ResponseResult<String> responseResult = fileFeignClient.uploadFile(multipartFile);
            String fileUploadPath = responseResult.getData();
            return UrlUtils.removeUrlDomainName(fileUploadPath);
        } catch (Exception ex) {
            throw new BusinessException("上传头像文件失败：" + ex.toString());
        }
    }


    private String uploadLocalFileToOss(String localFilePath, String fileName){
        File localFile = new File(localFilePath);
        OssPolicyDto policy = OssService.policy();
        String ossfilePath = policy.getDir() + fileName;
        String resultKey = OSSUtils.patchUpload(ossClient, ossProp.getBucket(),localFile, ossfilePath);
        LogUtils.info(">>>>>>>>resultKey:{}", resultKey);
        return resultKey;
    }
}

